package dj.service.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import dj.Constant;
import dj.dao.BaseDao;
import dj.model.Friend;
import dj.model.FriendExtend;
import dj.model.FriendGroup;
import dj.model.Tuser;
import dj.pageModel.Puser;
import dj.pageModel.TreeNode;
import dj.service.FriendService;
import dj.service.UserService;

@Service("friendService")
public class FriendServiceImpl implements FriendService {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(FriendServiceImpl.class);

	private BaseDao<Friend> friendDao;

	private BaseDao<FriendGroup> friendGroupDao;

	private UserService userService;

	public BaseDao<Friend> getFriendDao() {
		return friendDao;
	}

	@Autowired
	public void setFriendDao(BaseDao<Friend> friendDao) {
		this.friendDao = friendDao;
	}

	public BaseDao<FriendGroup> getFriendGroupDao() {
		return friendGroupDao;
	}

	@Autowired
	public void setFriendGroupDao(BaseDao<FriendGroup> friendGroupDao) {
		this.friendGroupDao = friendGroupDao;
	}

	public UserService getUserService() {
		return userService;
	}

	@Autowired
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public void saveFriend(Friend friend) {
		friendDao.save(friend);
		// 如果不是从数据库中加载 则放到内存中
		if (!Constant.GET_USER_FROM_DB) {
			setFriendToMap(friend);
			setHasFriendToMap(friend);
		}
	}

	public void updateFriend(Friend friend) {
		friendDao.update(friend);
	}

	public void deleteFriend(Friend friend) {
		friendDao.delete(friend);
		if (!Constant.GET_USER_FROM_DB) {
			removeFriendFromMap(friend);
			removeHasFriendFromMap(friend);
		}
		
	}

	public void saveFriendGroup(FriendGroup friendGroup) {
		friendGroupDao.save(friendGroup);

		setFriendGroupToMap(friendGroup);
	}

	public void updateFriendGroup(FriendGroup friendGroup) {
		friendGroupDao.update(friendGroup);
	}

	public void initFriendMap() {
		logger.info("加载好友...");
		List<Friend> ls = friendDao.find("from Friend");
		Constant.FRIEND_USER_KEY_MAP = new LinkedHashMap<String, List<Friend>>();
		Constant.HASFRIEND_USER_KEY_MAP = new LinkedHashMap<String, List<Friend>>();
		for (Friend friend : ls) {
			setFriendToMap(friend);
			setHasFriendToMap(friend);
		}
	}

	/**
	 * 把好友放到内存中
	 * 
	 * @param friend
	 */
	public void setFriendToMap(Friend friend) {
		List<Friend> friendls = Constant.FRIEND_USER_KEY_MAP.get(friend.getUserid());
		if (null == friendls) {
			friendls = new ArrayList<Friend>();
			friendls.add(friend);
			Constant.FRIEND_USER_KEY_MAP.put(friend.getUserid(), friendls);
		} else {
			friendls.add(friend);
		}
	}

	/**
	 * 把好友从内存中移除
	 * 
	 * @param friend
	 */
	public void removeFriendFromMap(Friend friend) {
		List<Friend> friendls = Constant.FRIEND_USER_KEY_MAP.get(friend.getUserid());
		if (null != friendls) {
			friendls.remove(friend);
		}
	}

	/**
	 * 好友id为key的map
	 * 
	 * @param friend
	 */
	public void setHasFriendToMap(Friend friend) {
		List<Friend> hasFriendls = Constant.HASFRIEND_USER_KEY_MAP.get(friend.getTuser().getId());
		if (null == hasFriendls) {
			hasFriendls = new ArrayList<Friend>();
			hasFriendls.add(friend);
			Constant.HASFRIEND_USER_KEY_MAP.put(friend.getTuser().getId(), hasFriendls);
		} else {
			hasFriendls.add(friend);
		}
	}
	
	/**
	 * 移除好友id为key的map
	 * @param friend
	 */
	public void removeHasFriendFromMap(Friend friend) {
		List<Friend> hasFriendls = Constant.HASFRIEND_USER_KEY_MAP.get(friend.getTuser().getId());
		if (null != hasFriendls) {
			hasFriendls.remove(friend);
		}
	}

	public Friend getFriend(String userid, String friendid) {
		Friend friend = null;
		if (Constant.GET_USER_FROM_DB) {
			Map<String, Object> params = new LinkedHashMap<String, Object>();
			params.put("userid", userid);
			params.put("friendid", friendid);
			friend = friendDao.get("from Friend where userid=:userid and tuser=:friendid", params);
		} else {
			List<Friend> ls = Constant.FRIEND_USER_KEY_MAP.get(userid);
			if (null != ls) {
				for (Friend f : ls) {
					if (f.getTuser().getId().equals(friendid)) {
						friend = f;
						break;
					}
				}
			}
		}

		return friend;
	}

	public List<Friend> getFriendList(Puser user) {
		List<Friend> ls = new ArrayList<Friend>();
		if (Constant.GET_USER_FROM_DB) {
			Map<String, Object> params = new LinkedHashMap<String, Object>();
			params.put("userid", user.getId());
			ls = friendDao.find("from Friend where userid=:userid", params);
		} else {
			ls = Constant.FRIEND_USER_KEY_MAP.get(user.getId());
		}

		return ls;
	}

	public List<Friend> getHasFriendList(Puser user) {
		List<Friend> ls = new ArrayList<Friend>();

		if (Constant.GET_USER_FROM_DB) {
			Map<String, Object> params = new LinkedHashMap<String, Object>();
			params.put("friendid", user.getId());
			ls = friendDao.find("from Friend where friendid=:friendid", params);
		} else {
			ls = Constant.HASFRIEND_USER_KEY_MAP.get(user.getId());
		}

		return ls;
	}

	public void initFriendGroupMap() {
		logger.info("加载好友组...");
		List<FriendGroup> ls = friendGroupDao.find("from FriendGroup");
		// 公共组
		List<FriendGroup> commonGroup = new ArrayList<FriendGroup>();
		for (FriendGroup fg : ls) {
			// userid为-1的组 都是公共组
			if ("-1".equals(fg.getUserid())) {
				commonGroup.add(fg);
				continue;
			}
			setFriendGroupToMap(fg);
		}
		List<Tuser> allUser = userService.getAllUser();

		// 初始化公共好友组
		Constant.COMMON_FRIENDGROUP = commonGroup;
		// 把公共组加到所有用户下面
		for (Tuser user : allUser) {
			if (null != Constant.FRIENDGROUP_USER_KEY_MAP.get(user.getId())) {
				Constant.FRIENDGROUP_USER_KEY_MAP.get(user.getId()).addAll(commonGroup);
			} else {
				List<FriendGroup> fgls = new ArrayList<FriendGroup>(commonGroup);
				Constant.FRIENDGROUP_USER_KEY_MAP.put(user.getId(), fgls);
			}
		}
	}

	/**
	 * 把一个组放到内存中
	 * 
	 * @param fg
	 */
	public void setFriendGroupToMap(FriendGroup fg) {
		if (null == Constant.FRIENDGROUP_USER_KEY_MAP.get(fg.getUserid())) {
			List<FriendGroup> fgls = new ArrayList<FriendGroup>();
			fgls.add(fg);
			Constant.FRIENDGROUP_USER_KEY_MAP.put(fg.getUserid(), fgls);
		} else {
			Constant.FRIENDGROUP_USER_KEY_MAP.get(fg.getUserid()).add(fg);
		}
	}

	public void initCommonFriendGroup() {
		logger.info("加载公共好友组...");
		Constant.COMMON_FRIENDGROUP = friendGroupDao.find("from FriendGroup where userid='-1'");
	}

	public List<FriendGroup> getFriendGroup(String userid) {
		List<FriendGroup> ls = new ArrayList<FriendGroup>();
		if (Constant.GET_USER_FROM_DB) {
			Map<String, Object> params = new LinkedHashMap<String, Object>();
			params.put("userid", userid);
			ls = friendGroupDao.find("from FriendGroup where userid=:userid or userid='-1'", params);
		} else {
			ls = Constant.FRIENDGROUP_USER_KEY_MAP.get(userid);
		}
		return ls;
	}

	public List<TreeNode> getFriendTree(List<Friend> ls) throws IllegalAccessException, InvocationTargetException {
		List<TreeNode> tree = new ArrayList<TreeNode>();
		for (Friend f : ls) {
			TreeNode tn = getFriendNode(f);
			tree.add(tn);
		}
		return tree;
	}

	public TreeNode getFriendNode(Friend f) {
		TreeNode tn = new TreeNode();
		boolean online = false;
		if (null != Constant.onlineUser.get(f.getTuser().getId())) {
			online = true;
		}
		String remarkName = "";
		if (null != f.getFriendExtends() && f.getFriendExtends().size() > 0) {
			FriendExtend fe = f.getFriendExtends().iterator().next();
			remarkName = fe.getRemarkName();
		}
		String friendName = "";
		if ("".equals(remarkName)) {
			if (null != f.getTuser().getDisplayName() && !"".equals(f.getTuser().getDisplayName().trim())) {
				friendName = f.getTuser().getDisplayName() + "(" + f.getTuser().getName() + ")";
			} else {
				friendName = f.getTuser().getName();
			}
		} else {
			friendName = remarkName + "(" + f.getTuser().getName() + ")";
		}

		tn.setId(f.getTuser().getId());
		tn.setText(friendName);
		if (online) {
			tn.setIconCls("icon-user");
		}
		Map<String, Object> attribute = new LinkedHashMap<String, Object>();
		attribute.put("online", online);
		attribute.put("friendName", f.getTuser().getName());
		attribute.put("displayName", f.getTuser().getDisplayName());
		attribute.put("groupid", f.getGroupid());
		attribute.put("remarkName", remarkName);
		tn.setAttributes(attribute);

		return tn;
	}

	public List<Friend> getFriendListByGroupid(Puser user, String groupid) {
		Map<String, Object> params = new LinkedHashMap<String, Object>();
		params.put("userid", user.getId());
		params.put("groupid", groupid);
		List<Friend> ls = friendDao.find("from Friend where userid=:userid and groupid=:groupid", params);
		return ls;
	}

}
